package advice;

import java.io.ByteArrayOutputStream;
import java.io.PrintStream;
import java.lang.reflect.Method;

import org.apache.log4j.Logger;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.Signature;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.aspectj.lang.reflect.MethodSignature;
@Aspect
public class ExceptionManager {
	private static Logger logger = Logger.getLogger(ExceptionManager.class);
	@Pointcut("execution(* service.*.*(..)))")
    private void servicePointcut() {
    }
	
	@Around(value = "ExceptionManager.servicePointcut()")
    public Object aroundService(ProceedingJoinPoint proceedingJoinPoint) throws Throwable {
		Object result = null;
        try {
            result = (String) proceedingJoinPoint.proceed();
        } catch (Exception e) {
        	e.printStackTrace();
        	Signature sig = proceedingJoinPoint.getSignature();
            MethodSignature msig = (MethodSignature) sig;
            Object target = proceedingJoinPoint.getTarget();
            Method currentMethod = target.getClass().getMethod(msig.getName(), msig.getParameterTypes());
        	
            ByteArrayOutputStream baos = new ByteArrayOutputStream();  
            e.printStackTrace(new PrintStream(baos));  
            String exception = baos.toString();
            logger.error("caught exception in " + currentMethod.toString() +" : " + exception);
            result = null;
        }
        finally {
        	if(logger.isInfoEnabled())
        		logger.info("request result: " + result);
		}
        return result;
	}
	
	@Pointcut("execution(* net.socket.server.*.*(..)))")
    private void serverPointcut() {
    }
	
	@Around(value = "ExceptionManager.serverPointcut()")
    public Object aroundServer(ProceedingJoinPoint proceedingJoinPoint) throws Throwable {
		Object o1 = null;
        try {
            o1 = proceedingJoinPoint.proceed();
        } catch (Exception e) {
        	Signature sig = proceedingJoinPoint.getSignature();
            MethodSignature msig = (MethodSignature) sig;
            Object target = proceedingJoinPoint.getTarget();
            Method currentMethod = target.getClass().getMethod(msig.getName(), msig.getParameterTypes());
        	
            ByteArrayOutputStream baos = new ByteArrayOutputStream();  
            e.printStackTrace(new PrintStream(baos));  
            String exception = baos.toString();
            logger.error("caught exception in " + currentMethod.toString() +" : " + exception);
        }
        finally {
		}
        return o1;
	}
	
	
	@Pointcut("execution(* manager.*.*.*(..)))")
    private void managerPointcut() {
    }
	
	@Around(value = "ExceptionManager.managerPointcut()")
    public Object aroundManager(ProceedingJoinPoint proceedingJoinPoint) throws Throwable {
		Object o1 = null;
        try {
            o1 = proceedingJoinPoint.proceed();
        } catch (Exception e) {
        	System.out.println("i got a exception");
        	e.printStackTrace();
        	Signature sig = proceedingJoinPoint.getSignature();
            MethodSignature msig = (MethodSignature) sig;
            Object target = proceedingJoinPoint.getTarget();
            Method currentMethod = target.getClass().getMethod(msig.getName(), msig.getParameterTypes());
        	
            ByteArrayOutputStream baos = new ByteArrayOutputStream();  
            e.printStackTrace(new PrintStream(baos));  
            String exception = baos.toString();
            logger.error("caught exception in " + currentMethod.toString() +" : " + exception);
        }
        finally {
		}
        return o1;
	}
	
	
	
}
